package com.gcosc.hly.codejava.Utils;

import com.alibaba.fastjson.JSONObject;
import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.gcosc.hly.codejava.result.Code;
import com.gcosc.hly.codejava.result.Token;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.nio.charset.StandardCharsets;
import java.util.Base64;

@Component
public class TokenUtils {
    @Value("${token.privateKey}")
    private String privateKey;

    /**
     * 加密token.
     */
    public String getToken(Token to) {
        //这个是放到负载payLoad 里面,魔法值可以使用常量类进行封装.
        String token = JWT
                .create()
                .withClaim("id" ,to.getId())
                .withClaim("root", to.getRoot())
                .withClaim("timeStamp", to.getTime())
                .sign(Algorithm.HMAC256(privateKey));
        return token;
    }

    public String getToken(int id, int root) {
        return getToken(new Token(id, root, System.currentTimeMillis()));
    }

    /**
     * 解析token.
     * (优化可以用常量固定魔法值+使用DTO在 mvc 之前传输数据，而不是 map,这里因为篇幅原因就不做了)
     * {
     * "userId": "3412435312",
     * "userRole": "ROLE_USER",
     * "timeStamp": "134143214"
     * }
     */
    public Token parseToken(String token) {
        try {
            DecodedJWT decodedjwt = JWT.require(Algorithm.HMAC256(privateKey))
                    .build().verify(token);
            Claim userId = decodedjwt.getClaim("id");
            Claim userRole = decodedjwt.getClaim("root");
            Claim timeStamp = decodedjwt.getClaim("timeStamp");
            return new Token(userId.asInt(), userRole.asInt(),timeStamp.asLong());
        }catch (Exception e){
            Code.TOKEN_ERR("登录验证失败，请重新登录");
        }
        return null;
    }

    public JSONObject parseTokenJSONObject(String token){
        String[] splitToken = token.split("\\.");
        String decodedToken = new String(Base64.getUrlDecoder().decode(splitToken[1]), StandardCharsets.UTF_8);
        JSONObject jsonObject = JSONObject.parseObject(decodedToken);
        System.out.println(jsonObject.get("info"));
        return jsonObject.getJSONObject("info");
    }
}

